﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using JihankiLib;

namespace ConsoleJihanki
{
    class ConsoleJihanItemBox : JihankiItemBoxMachine
    {
        //Todo: ItemReplenishedイベントが関わる機能の実装

        private class ConsoleJihankiResult : IJihankiResult
        {
            private string msg;

            public ConsoleJihankiResult(string msg)
            {
                this.msg = msg;
            }
        
            public void OpenResult()
            {
                Console.WriteLine(msg);
            }
        }

        public override void OnNext(JihankiMessage value)
        {
            //Todo: 各MessageProcesserクラスを作成し、そこにメッセージごとの処理を移動する。

            if (value.GetType() == typeof(AddedMoneyMessage))
            {
                var total = ((AddedMoneyMessage)value).Total.Value;
                AddedMoneyProcess(total);
            }

            if (value.GetType() == typeof(JihanItemBoxEmptMessage))
            {
                var msg = value as JihanItemBoxEmptMessage;
                Console.WriteLine(String.Format("商品の在庫が無くなりました！！(Item{0})", msg.Unit.No));
            }
        }

        private class ItemStockSummary
        {
            public int UnitNo;
            public int Value;

            public ItemStockSummary(ItemStock stock)
            {
                this.UnitNo = stock.UnitNo;
                this.Value = stock.Value;
            }

            public override string ToString()
            {
                return String.Format("Item{0}({1}円)", UnitNo, Value);
            }
        }

        private class ItemStockManager
        {
            private List<ItemStock> stocks = new List<ItemStock>();

            public ItemStockManager()
            {
                //面倒なのでここで全部定義しちゃう。
                stocks.Add(new ItemStock(1, 120));
                stocks.Add(new ItemStock(2, 120));
                stocks.Add(new ItemStock(3, 150));
                stocks.Add(new ItemStock(4, 200));
                stocks.Add(new ItemStock(5, 230));
                for (var i = 0; i < stocks.Count; i++)
                    InitializeItemStock(i + 1, 3, stocks[i]);
            }

            private void InitializeItemStock(int no, int count, ItemStock stock)
            {
                for (int i = 0; i < count; i++)
                    stock.Add(new ConsoleJihankiResult(String.Format("アイテム{0}-{1}のお買い上げありがとうございます！！", no, i + 1)));
            }

            public ItemStock GetStock(int no)
            {
                return stocks.First(s => s.UnitNo == no);
            }

            public List<ItemStockSummary> GetCanBayItemInformation(int value)
            {
                var ret = new List<ItemStockSummary>();
                foreach (var sk in stocks)
                {
                    if (sk.ExistStock() && sk.Value <= value)
                        ret.Add(new ItemStockSummary(sk));
                }
                return ret;
            }
        }

        private ItemStockManager stockManager = new ItemStockManager();

        private void AddedMoneyProcess(int total)
        {
            var items = stockManager.GetCanBayItemInformation(total);
            if(items.Count == 0)
                return;
            var min = items[0];
            var max = items[items.Count - 1];

            var itemsStr = "";
            items.ForEach(s => { itemsStr += s.ToString() + ","; });
            Console.WriteLine("次の商品が購入可能です。 [" + itemsStr.Substring(0,itemsStr.Length-1) + "]");
            
            Console.Write("商品を購入しますか？(yes/no)：");
            if (Console.ReadLine().ToLower() != "yes")
                return;

            Console.Write("購入商品Noを入力してください。：");
            var rawItemNo = Console.ReadLine();
            int itemNo;

            if (!int.TryParse(rawItemNo, out itemNo))
                return;
            if (itemNo < min.UnitNo || itemNo > max.UnitNo)
                return;
            
            PurchaseItem(itemNo, total, stockManager.GetStock(itemNo));
        }       
    }
}
